/**
 * Controller for all consolidation-related management functionality
 */
Ext.define('Sisconsolid.controller.Consolidation', {
    extend: 'Sisconsolid.controller.Base',
    stores: [
        'Consolidations'
    ],
    views: [
        'consolidation.List',
        'consolidation.edit.Form',
        'consolidation.edit.Window',
        'consolidation.search.Form',
        'consolidation.search.Window'
    ],
    refs: [
        {
            ref: 'ConsolidationList',
            selector: '[xtype=consolidation.list]'
        },
        {
            ref: 'ConsolidationEditWindow',
            selector: '[xtype=consolidation.edit.window]'
        },
        {
            ref: 'ConsolidationEditForm',
            selector: '[xtype=consolidation.edit.form]'
        },
        {
            ref: 'ConsolidationSearchWindow',
            selector: '[xtype=consolidation.search.window]'
        },
        {
            ref: 'ConsolidationSearchForm',
            selector: '[xtype=consolidation.search.form]'
        } 
    ],
    init: function() {
        this.listen({
            controller: {},
            component: {
                'grid[xtype=consolidation.list]': {
                    beforerender: this.loadRecords,
                    itemdblclick: this.edit,
                    itemcontextmenu: this.showContextMenu
                },
                'grid[xtype=consolidation.list] button#add': {
                    click: this.add
                },
                'grid[xtype=consolidation.list] button#search': {
                    click: this.showSearchWindow
                },
                'grid[xtype=consolidation.list] button#clear': {
                    click: this.clearSearch
                },
                'window[xtype=consolidation.edit.window] button#save': {
                    click: this.save
                },
                'window[xtype=consolidation.edit.window] button#cancel': {
                    click: this.close
                },
				'window[xtype=consolidation.search.window] button#search': {
					click: this.search
				},
				'window[xtype=consolidation.search.window] button#cancel': {
					click: this.close
				},
				'form[xtype=consolidation.edit.form] combobox[name=idProvince]': {
					change: this.filterCity
				},
				'form[xtype=consolidation.edit.form] combobox[name=idCity]': {
					beforequery: this.checkProvince,
					change: this.filterNeighborhoodAndCity
				},
				'form[xtype=consolidation.edit.form] combobox[name=idNeighborhood]': {
					beforequery: this.checkCityFromNeighborhood
				},
				'form[xtype=consolidation.edit.form] combobox[name=idStreet]': {
					beforequery: this.checkCityFromStreet
				},
				'form[xtype=consolidation.edit.form] radiogroup[name=attendedChurch]': {
					change: this.changeAttendedChurch
				},
				'form[xtype=consolidation.edit.form] radiogroup[name=attendCell]': {
					change: this.changeAttendCell
				}
            },
            global: {},
            store: {},
            proxy: {} 
        });
    },
    /**
     * Displays context menu 
     * @param {Ext.view.View} view
     * @param {Ext.data.Model} record 
     * @param {HTMLElement} item
     * @param {Number} index
     * @param {Ext.EventObject} e
     * @param {Object} eOpts
     */
    showContextMenu: function( view, record, item, index, e, eOpts ) {
        var me = this;
        // stop event so browser's normal right-click action doesn't continue
        e.stopEvent();
        // if a menu doesn't already exist, create one
        if( !item.contextMenu ) {
            // add menu
            item.contextMenu = new Ext.menu.Menu({
                items: [
                    {
                        text: translations.editConsolidation,
                        iconCls: 'icon_edit',
                        handler: function( item, e ) {
                            me.edit( view, record, item, index, e, eOpts );
                        }
                    },
                    {
                        text: translations.cancelConsolidation,
                        iconCls: 'icon_delete',
                        handler: function( item, e ) {
                            me.cancel( record );
                        }
                    }
                ]
            })
        }
        // show menu relative to item which was right-clicked
        item.contextMenu.showBy( item );
    },
    /**
     * Loads the grid's store
     * @param {Ext.grid.Panel} grid
     * @param {Object} eOpts
     */
    loadRecords: function( grid, eOpts ) {
        var me = this,
            store = grid.getStore();
        // clear any fliters that have been applied
        store.clearFilter( true );
        // load the store
        store.load();
    },
    /**
     * Handles request to edit
     * @param {Ext.view.View} view
     * @param {Ext.data.Model} record 
     * @param {HTMLElement} item
     * @param {Number} index
     * @param {Ext.EventObject} e
     * @param {Object} eOpts
     */
    edit: function( view, record, item, index, e, eOpts ) {
        var me = this;
        // show window
        me.loadDetail( record, me, me.showEditWindow );
    },
    /**
     * Creates a new record and prepares it for editing
     * @param {Ext.button.Button} button
     * @param {Ext.EventObject} e
     * @param {Object} eOpts
     */
    add: function( button, e, eOpts ) {
        var me = this,
            record = Ext.create( 'Sisconsolid.model.Consolidation' );
			//record.data.civilStatus= 1;
			//record.data.sex = "M";
        // show window
        me.showEditWindow( record );
    },
    /**
     * Persists edited record
     * @param {Ext.button.Button} button
     * @param {Ext.EventObject} e
     * @param {Object} eOpts
     */
    save: function( button, e, eOpts ) {
        var me = this,
            grid = me.getConsolidationList(),
            store = grid.getStore(),
            win = button.up( 'window' ),
            form = win.down( 'form' ),
            record = form.getRecord(),
            values = form.getValues(),
            callbacks;

        // set values of record from form
        record.set( values );
        // check if form is even dirty...if not, just close window and stop everything...nothing to see here
        if( !record.dirty ) {
            win.close();
            return;
        }
		
		if (!record.data.attendedChurch) {
			win.down( 'form' ).down('textfield[name=whichChurch]').allowBlank = true;		
		}
		if (!record.data.attendCell) {
			win.down( 'form' ).down('combobox[name=idCell]').allowBlank = true;		
		}
		if (!form.isValid()) {
			Ext.Msg.alert(translations.error, translations.enterAllFieldsMessage);
			return;
		}
        // setup generic callback config for create/save methods
        callbacks ={
            success: function( records, operation ) {
				Ext.Msg.alert(translations.result, translations.successSavingConsolidation);
                win.close();
				store.load();
            },
            failure: function( records, operation ) {
                // if failure, reject changes in store
                store.rejectChanges();
            }
        };
        // mask to prevent extra submits		
        Ext.getBody().mask(translations.savingConsolidation);
        // if new record...
        if( record.phantom ) {
            // reject any other changes
            store.rejectChanges();
            // add the new record
            store.add( record );
        }
        // persist the record
        store.sync( callbacks );
    },
    /**
     * Persists edited record
     * @param {Ext.button.Button} button
     * @param {Ext.EventObject} e
     * @param {Object} eOpts
     */
    close: function( button, e, eOpts ) {
        var me = this,
            win = button.up( 'window' );
        // close the window
        win.close();
    },
    /**
     * Displays context menu 
     * @param {Ext.data.Model[]} record
     */
    cancel: function( record ) {
        var me = this,
            store = record.store;
        // show confirmation before continuing
        Ext.Msg.confirm( translations.attention, translations.confirmRemoveConsolidation, function( buttonId, text, opt ) {
            if( buttonId=='yes' ) {
				Ext.getBody().mask(translations.removingConsolidation);
                store.remove( record );
                store.sync({
				
					success: function(consolidation) {
						Ext.Msg.alert(translations.result, translations.successCancelingConsolidation);
					},
                    /**
                     * On failure, add record back to store at correct index
                     * @param {Ext.data.Model[]} records
                     * @param {Ext.data.Operation} operation
                     */
                    failure: function( records, operation ) {
                        store.rejectChanges();
						Ext.Msg.alert(translations.result, translations.errorCancelingConsolidation);
                    }
                })
            }
        })
    },
    /**
     * Displays common editing form for add/edit operations
     * @param {Ext.data.Model} record
     */
    showEditWindow: function( record ) {
        var me = this,
            win = me.getConsolidationEditWindow(),
            isNew = record.phantom;
        // if window exists, show it; otherwise, create new instance
        if( !win ) {
            win = Ext.widget( 'consolidation.edit.window', {
                title: isNew ? translations.addConsolidation : translations.editConsolidation
            });
        }
        // show window
        win.show();
        // load form with data
        win.down( 'form' ).loadRecord( record );		
    },
	/**
	 * Executes search
	 * @param {Ext.button.Button} button
	 * @param {Ext.EventObject} e
	 * @param {Object} eOpts
	 */
	search: function( button, e, eOpts ) {
		var me = this,
			win = me.getConsolidationSearchWindow(),
			form = win.down( 'form' ),
			grid = me.getConsolidationList(),
			store = grid.getStore(),
			values = form.getValues(),
			filters=[];
		// loop over values to create filters
		Ext.Object.each( values, function( key, value, myself ) {
			if( !Ext.isEmpty( value ) ) {
				filters.push({
					property: key,
					value: value
				})
			}
		});
		// clear store filters
		store.clearFilter( true ); // silent=true tells store not to reload
		store.filter( filters );
		// close window
		win.hide();
	},
    /**
     * Displays common search form for sarch operations
     * @param {Ext.data.Model} record
     */
    showSearchWindow: function() {
        var me = this,
            win = me.getConsolidationSearchWindow();            
        // if window exists, show it; otherwise, create new instance
        if( !win ) {
            win = Ext.widget( 'consolidation.search.window', {
                title: translations.filterConsolidation
            });
        }
        // show window
        win.show();
        // load form with data
        // en caso de por defecto win.down( 'form' ).loadRecord( record );
    },
	/**
	 * Clears search form and resets results
	 * @param {Ext.button.Button} button
	 * @param {Ext.EventObject} e
	 * @param {Object} eOpts
	 */
	clearSearch: function( button, e, eOpts ) {
		var me = this,
			grid = me.getConsolidationList(),
			store = grid.getStore();
		// clear filter
		store.clearFilter( false ); // silent=false tells store to reload 
		// reset form
		var win = me.getConsolidationSearchWindow();
		win.down('form').form.reset();
	},
	/**
	 * Filters City combobox based on selection in Province combobox
	 * @param {Ext.form.field.ComboBox} combobox
	 * @param {Object} newValue
	 * @param {Object} oldValue
	 * @param {Object} eOpts
	 */
	filterCity: function( combobox, newValue, oldValue, eOpts ) {
		var me = this,
			city = combobox.up( 'form' ).down( '[name=idCity]' ),
			store = city.getStore(),
			filters = [
				{
					property: 'idProvince',
					value: newValue
				}
			];
		
		store.clearFilter( true );
		store.filter( filters);	
		
		var record = combobox.up( 'form' ).getRecord();
		if (!record.dirty) {
			city.setValue(record.data.idCity);
		}
		//problems with refreshing times
		if(store.data.items.length < 1)	{
			setTimeout(function() {
				me.filterCity(combobox, newValue, oldValue, eOpts)
			});
		}
	},
	/**
	 * Interrupts City combobox query to check if Province is defined
	 * @param {Object} queryPlan
	 * @param {Object} eOpts
	 */
	checkProvince: function( queryPlan, eOpts ) {
		var me = this,
			province = queryPlan.combo.up( 'form' ).down( '[name=idProvince]' );
		// don't allow selection until province is selected
		if( Ext.isEmpty( province.getValue() ) ) {
			Ext.Msg.alert( 'Por favor seleccione una provincia antes de elegir una ciudad' );
			// cancel query
			queryPlan.cancel = true;
		}
	},
	/**
	 * Filters Neighborhood and Street comboboxs based on selection in City combobox
	 * @param {Ext.form.field.ComboBox} combobox
	 * @param {Object} newValue
	 * @param {Object} oldValue
	 * @param {Object} eOpts
	 */
	filterNeighborhoodAndCity: function( combobox, newValue, oldValue, eOpts ) {
		var me = this,
			neighborhood = combobox.up( 'form' ).down( '[name=idNeighborhood]' ),
			store = neighborhood.getStore(),
			filters = [
				{
					property: 'idCity',
					value: newValue
				}
			];
		store.clearFilter( true );
		store.filter( filters );
		
		var record = combobox.up( 'form' ).getRecord();
		if (!record.dirty) {
			neighborhood.setValue(record.data.idNeighborhood);
		}
		
		var street = combobox.up( 'form' ).down( '[name=idStreet]' );
		store = street.getStore();
		store.clearFilter( true );
		store.filter( filters );
		
		if (!record.dirty) {
			street.setValue(record.data.idStreet);
		}
	},
	/**
	 * Interrupts Neighborhood combobox query if City is not defined
	 * @param {Object} queryPlan
	 * @param {Object} eOpts
	 */
	checkCityFromNeighborhood: function( queryPlan, eOpts ) {
		var me = this,
			city = queryPlan.combo.up( 'form' ).down( '[name=idCity]' );
		if( Ext.isEmpty( city.getValue() ) ) {
			Ext.Msg.alert( 'Por favor seleccione una ciudad antes de elegir un barrio' );
			queryPlan.cancel = true;
		}
	},
	/**
	 * Interrupts Street combobox query if City is not defined
	 * @param {Object} queryPlan
	 * @param {Object} eOpts
	 */
	checkCityFromStreet: function( queryPlan, eOpts ) {
		var me = this,
			city = queryPlan.combo.up( 'form' ).down( '[name=idCity]' );
		if( Ext.isEmpty( city.getValue() ) ) {
			Ext.Msg.alert( 'Por favor seleccione una ciudad antes de elegir una calle' );
			queryPlan.cancel = true;
		}
	},
    /**
     * Refresh the grid list
     */
    refresh: function() {
        var me = this,
            grid = me.getConsolidationList(),
            store = grid.getStore();
        Ext.getBody().mask( 'Refreshing Consolidations...' );
        // persist the record
        store.load();
    },
	changeAttendedChurch: function (field, newValue, oldValue) {
		if (newValue.attendedChurch == true) {
			Ext.ComponentQuery.query('[name=whichChurch]')[0].show();
			Ext.ComponentQuery.query('[id=idWhichChurchSpace]')[0].hide();			
		} else {
			Ext.ComponentQuery.query('[name=whichChurch]')[0].hide();
			Ext.ComponentQuery.query('[id=idWhichChurchSpace]')[0].show();
		}
	},
	changeAttendCell: function (field, newValue, oldValue) {
		if (newValue.attendCell == true) {
			Ext.ComponentQuery.query('[name=idCell]')[0].show();
			Ext.ComponentQuery.query('[id=idWhichCellSpace]')[0].hide();
		} else {
			Ext.ComponentQuery.query('[name=idCell]')[0].hide();
			Ext.ComponentQuery.query('[id=idWhichCellSpace]')[0].show();
		}
	}
});